package me.keiwu.admin.job;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import me.keiwu.admin.rpc.ChallengeRpc;
import me.keiwu.admin.rpc.NoticeRpc;
import me.keiwu.admin.rpc.UserRpc;
import me.keiwu.admin.util.ExceptionUtil;
import me.keiwu.pub.data.ResponseV2;
import me.keiwu.pub.data.service.UserInfoBean;
import me.keiwu.pub.service.WXService;
import me.keiwu.pub.util.CacheUtil;
import me.keiwu.pub.util.DateUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Anthony on 23/03/2018.
 */
@Component
public class WXTemplateMsgJob {
    @Autowired
    private CacheUtil cacheUtil;
    @Autowired
    private UserRpc userRpc;
    @Autowired
    private WXService wxService;
    @Autowired
    private ChallengeRpc challengeRpc;
    @Autowired
    private NoticeRpc noticeRpc;
    @Autowired
    private ExceptionUtil exceptionUtil;

    private static final Logger logger = LoggerFactory.getLogger(WXTemplateMsgJob.class);
    /**
     *
     * 对5天未上线的用户发消息
     *
     */
    @Scheduled(cron = "0 0 22 * * ?")
    public void runLoginHint(){
        int page = 0;
        int size = 100;
        this.exceptionLog("sendLoginHintTmpMsg", "start at 22:00");

        while (true) {
            String inactiveUsers = userRpc.getInactiveUsers(page, size);
            logger.info("********sendLoginHintTmpMsg********");
            logger.info(inactiveUsers);
            JSONObject data = JSON.parseObject(inactiveUsers);
            List list = data.getJSONArray("content");
            for (Object obj : list) {
                try {
                    JSONObject json = (JSONObject) obj;
                    Long userId = json.getLong("id");
                    UserInfoBean user = JSON.parseObject(userRpc.userInfo(userId), UserInfoBean.class);

                    if (user != null){
                        String userFormStr = userRpc.getUserForm(user.getId());
                        if (StringUtils.isBlank(userFormStr)) {
                            this.exceptionLog("sendLoginHintTmpMsg", "no formid");
                            continue;
                        }
                        Map<String, Object> formMap = JSON.parseObject(userFormStr, Map.class);
                        String formId = (String)formMap.get("formId");
                        Long form_db_id = ((Number)formMap.get("id")).longValue();

                        Map<String, Object> map = new HashMap<String, Object>();
                        map.put("formId", formId);
                        map.put("templateMsgType",2);
                        ResponseV2 resp = wxService.sendTemplateMsg(null, JSONObject.toJSONString(user),"pages/home/home",map);
                        if(resp.getCode() == HttpStatus.OK.value() || resp.getCode() == 1) {
                            userRpc.deleteUsedForm(form_db_id);

                        } else {
                            this.exceptionLog("sendLoginHintTmpMsg", resp.getMsg());
                        }
                    }
                } catch (Exception e) {
                    this.exceptionLog("sendLoginHintTmpMsg", e.getLocalizedMessage());
                    continue;
                }
            }
            Integer totalPages = data.getInteger("totalPages");
            if (totalPages < ++page)
                break;
        }
    }

    /**
     *
     * 14点发送第一波挑战推送
     *
     */
    @Scheduled(cron = "0 0 14 * * ?")
    public void challengeInviteNoticeFirstJob() {
        this.exceptionLog("sendChallengeInviteTmpMsg", "start at 14:00");

        sendChallengeInviteNotice();
    }

    /**
     *
     * 18点发送第二波挑战推送
     *
     */
    @Scheduled(cron = "0 0 18 * * ?")
    public void challengeInviteNoticeSecondJob() {
        this.exceptionLog("sendChallengeInviteTmpMsg", "start at 18:00");

        sendChallengeInviteNotice();
    }

    private void sendChallengeInviteNotice() {
        int page = 0;
        int size = 10;

        Date now = DateUtil.getCurrentTime();

        int nowHour = DateUtil.getHourOfDay(now);

        int startTime = 0;
        int endTime = 0;
        String keyTail = "14";
        if (nowHour >= 18){
            keyTail = "18";
            Calendar ca = Calendar.getInstance();
            ca.set(Calendar.HOUR_OF_DAY, 14);
            ca.set(Calendar.MINUTE, 0);
            ca.set(Calendar.SECOND, 0);
            ca.set(Calendar.MILLISECOND, 0);
            startTime = DateUtil.getUnixTime(ca.getTime());
            endTime = DateUtil.getUnixTime(now);

        } else {
            startTime = DateUtil.getUnixTime(DateUtil.getCurrentDay());
            endTime = DateUtil.getUnixTime(now);
        }


        while (true) {
            String challenges = noticeRpc.unreadChallengeNotice(page, size, startTime, endTime);
            JSONObject data = JSON.parseObject(challenges);
            List list = data.getJSONArray("content");
            for (Object obj : list) {
                try {
                    JSONObject json = (JSONObject) obj;
                    Long challengeId = json.getLong("uniqueKey");
                    Long noticeFromId = json.getLong("fromUser");
                    Long noticeToId = json.getLong("toUser");
                    String challengeStr = challengeRpc.findAllUserChallenge(challengeId);

                    if (StringUtils.isEmpty(challengeStr)) {
                        continue;
                    }
                    JSONObject challengeJson = JSON.parseObject(challengeStr);
                    int challengeStatus = challengeJson.getIntValue("state");
                    if (challengeStatus != 0) {
                        continue;
                    }
                    Long challengeInvitorId = challengeJson.getLong("initiator");
                    Long toUserId = null;
                    if (challengeInvitorId.equals(noticeFromId)) {
                        toUserId = noticeToId;
                    } else if (challengeInvitorId.equals(noticeToId)) {
                        toUserId = noticeFromId;
                    } else {
                        continue;
                    }
                    if (!cacheUtil.canTemplateMsgForChallengeInvite(toUserId, keyTail)){
                        this.exceptionLog("sendChallengeInviteTmpMsg", "sended :" + challengeId);
                        continue;
                    }

                    Long fromUserId = challengeInvitorId;

                    UserInfoBean fromUser = JSON.parseObject(userRpc.userInfo(fromUserId), UserInfoBean.class);
                    UserInfoBean toUser = JSON.parseObject(userRpc.userInfo(toUserId), UserInfoBean.class);

                    if (fromUser != null && toUser != null) {
                        String userFormStr = userRpc.getUserForm(toUser.getId());
                        if (StringUtils.isBlank(userFormStr)) {
                            this.exceptionLog("sendChallengeInviteTmpMsg", "no formid");

                            continue;
                        }
                        Map<String, Object> formMap = JSON.parseObject(userFormStr, Map.class);
                        String formId = (String)formMap.get("formId");
                        Long form_db_id = ((Number)formMap.get("id")).longValue();

                        Map<String, Object> map = new HashMap<String, Object>();

                        boolean cmtPoint = noticeRpc.checkNotRead(1,toUserId);
                        boolean stealPoint = noticeRpc.checkNotRead(0,toUserId);
                        boolean isRedPoint = cmtPoint || stealPoint;
                        // 根据 Challenge 获取比赛名称和截止时间
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        Date time = challengeJson.getDate("endDate");
                        String endTimeStr = sdf.format(time);
                        map.put("endTime", endTimeStr);
                        map.put("challengeName", "运动步行挑战赛");
                        map.put("formId", formId);
                        map.put("templateMsgType",5);
                        StringBuilder sbPage = new StringBuilder("pages/notification/notification?challengePoint=false&isRedPoint=");
                        sbPage.append(isRedPoint);
                        sbPage.append("&commentPoint=");
                        sbPage.append(cmtPoint);
                        sbPage.append("&stealGoldPoint=");
                        sbPage.append(stealPoint);
                        sbPage.append("&focus=2");
                        String pageUrl = sbPage.toString();
                        this.exceptionLog("sendChallengeInviteTmpMsg", "toUser:" + toUserId + " with challengeId:" + challengeId);
                        // 调用发送模板 传参发送消息
                        // 5 表示CHALLENGE_CREATED 比赛邀请通知
                        ResponseV2 resp = wxService.sendTemplateMsg(JSONObject.toJSONString(fromUser), JSONObject.toJSONString(toUser), pageUrl, map);
                        if(resp.getCode() == HttpStatus.OK.value()) {
                            cacheUtil.recordTemplateMsgForChallengeInvite(toUserId, keyTail);
                            userRpc.deleteUsedForm(form_db_id);
                            this.exceptionLog("sendChallengeInviteTmpMsg", "toUser:" + toUserId + " with formId:" + form_db_id);
                            
                        }else if (resp.getCode() == 1) {
                            userRpc.deleteUsedForm(form_db_id);
                            this.exceptionLog("sendChallengeInviteTmpMsg", "formid used");
                        }else {
                            this.exceptionLog("sendChallengeInviteTmpMsg", resp.getMsg());
                        }
                    }

                }catch (Exception e) {
                    this.exceptionLog("sendChallengeInviteTmpMsg", e.getLocalizedMessage());
                    continue;
                }
            }
            Integer totalPages = data.getInteger("totalPages");
            if (totalPages < ++page)
                break;
        }
    }

    /**
     *
     * 9.30发送比赛结果推送
     *
     */
    @Scheduled(cron = "0 30 09 * * ?")
    public void challengeResultNoticeJob() {
        this.exceptionLog("challengeResultNoticeJob", "start at 9:30");

        int page = 0;
        int size = 100;
        while (true) {
            String results = challengeRpc.yesterdayChallenges(page, size);
            logger.info("********sendChallengeInviteNotice********");
            logger.info(results);
            JSONObject data = JSON.parseObject(results);
            List list = data.getJSONArray("content");
            for (Object obj : list) {
                JSONObject challengeJson = (JSONObject) obj;
                Long challengeId = challengeJson.getLong("id");
                Long initiator = challengeJson.getLong("initiator");
                Long challenger = challengeJson.getLong("challenger");
                int initiatorStep = challengeJson.getIntValue("initiatorStep");
                int challengerStep = challengeJson.getIntValue("challengerStep");
                String fromNickName = challengeJson.getString("initiatorName");
                String toNickName = challengeJson.getString("challengerName");

                if (cacheUtil.canTemplateMsgForResult(challenger)) {
                    if (!cacheUtil.isAwardChallenge(challenger,challengeId)){
                        if (sendResultTemplateMsg(initiator,challenger,initiatorStep, challengerStep, fromNickName, toNickName, true)) {
                            cacheUtil.recordTemplateMsgForResult(challenger);
                        }
                    }
                }

                if (cacheUtil.canTemplateMsgForResult(initiator)) {
                    if (!cacheUtil.isAwardChallenge(initiator, challengeId)){
                        if (sendResultTemplateMsg(challenger,initiator,challengerStep, initiatorStep, fromNickName, toNickName, false)) {
                            cacheUtil.recordTemplateMsgForResult(initiator);
                        }
                    }
                }

            }
            Integer totalPages = data.getInteger("totalPages");
            if (totalPages < ++page)
                break;
        }
    }

    private boolean sendResultTemplateMsg(Long fromUserId, Long toUserId,
                                          Integer fromStep, Integer toStep,
                                          String fromNickName, String toNickName,
                                          boolean toIsChallenger) {
        String fromUser = userRpc.userInfo(fromUserId);
        String toUser = userRpc.userInfo(toUserId);
        String userFormStr = userRpc.getUserForm(toUserId);
        if (StringUtils.isBlank(userFormStr)) {
            exceptionUtil.logError(this.getClass(), "sendResultTemplateMsg", "no formid to :"+toUserId);
            return false;
        }
        Map<String, Object> formMap = JSON.parseObject(userFormStr, Map.class);
        String formId = (String)formMap.get("formId");
        Long form_db_id = ((Number)formMap.get("id")).longValue();

        String initiatorName = fromNickName;
        String vsMsg = fromNickName + " VS " + toNickName;
        if (!toIsChallenger) {
            initiatorName = toNickName;
            vsMsg = toNickName + " VS " + fromNickName;
        }

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("initiator",initiatorName);
        map.put("message",vsMsg);
        map.put("formId", formId);
        map.put("templateMsgType",1);
        map.put("step",toStep);
        if (Objects.equals(fromStep, toStep)) {
            map.put("result","平局");
            map.put("remark","马上点击查看比赛结果");

        } else if (toStep > fromStep) {
            map.put("result","胜利");
            map.put("remark","马上点击领取奖励");
        } else {
            map.put("result","不幸落马");
            map.put("remark","马上点击查看比赛结果");
        }
        String page = "pages/score/score";
        // 调用发送模板 传参发送消息
        // 0 表示CHALLENGE_CREATED 比赛结果通知

        ResponseV2 resp = wxService.sendTemplateMsg(fromUser, toUser, page, map);
        if(resp.getCode() == HttpStatus.OK.value()) {
            userRpc.deleteUsedForm(form_db_id);
            this.exceptionLog("sendResultTemplateMsg", "toUser:" + toUserId + " with formId:"+form_db_id);
            return true;

        }else if (resp.getCode() == 1) {
            userRpc.deleteUsedForm(form_db_id);
        }else {
            this.exceptionLog("sendResultTemplateMsg", resp.getMsg());
        }
        return false;
    }

    private void exceptionLog(String funcName, String msg) {
        exceptionUtil.logError(this.getClass(), funcName, msg);
    }

    public static void main(String[] args) {
        System.out.println(DateUtil.getUnixTime());
        System.out.println(new Date(1517974503*1000L).toString());
    }
}
